#include "unp.h"
#include <sys/select.h>

#define SETSIZE 10

int main(int argc, char *argv[])
{
    int listenfd, connfd, addrlen;
    struct sockaddr_in servaddr, cliaddr;
    int i, n, maxi, maxfd;
    fd_set rset, allset;
    int client[SETSIZE];
    char buf[MAXLINE];

    maxi = -1;
    FD_ZERO(&allset);
    FD_ZERO(&rset);
    listenfd = Socket(AF_INET, SOCK_STREAM, 0);
    maxfd = listenfd;
    FD_SET(listenfd, &allset);

    for (i=0; i<SETSIZE; i++) {
        client[i] = -1;
    }

    printf("listenfd=%d, maxfd=%d\n", listenfd, maxfd);

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(SERV_PORT);
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);

    Bind(listenfd, (SA*)&servaddr, sizeof(servaddr));
    Listen(listenfd, 15);


    for (; ;) {
        if (memcmp(&rset, &allset, sizeof(fd_set)) != 0) {
            printf("--------------assignment\n");
            print_hex("rset", &rset, sizeof(rset));
            print_hex("allset", &allset, sizeof(allset));
            printf("--------------end assignment\n");
        }
        rset = allset;
        select(maxfd+1, &rset, NULL, NULL, NULL);

        if (FD_ISSET(listenfd, &rset)) {
            addrlen = sizeof(struct sockaddr_in);
            connfd = Accept(listenfd, (SA*)&cliaddr, &addrlen);
            printf("listenfd=%d, connfd = %d, maxfd=%d\n", listenfd, connfd, maxfd);
            if (connfd > maxfd) {
                maxfd = connfd; /* for select */
            }
            FD_SET(connfd, &allset);
            print_hex("rset", &rset, sizeof(rset));
            print_hex("allset", &allset, sizeof(allset));
            for (i=0; i<SETSIZE; i++) {
                if (client[i] == -1) {
                    client[i] = connfd;
                    printf("%d:i=%d, listenfd=%d, connfd = %d, maxfd=%d\n", __LINE__, i, listenfd, connfd, maxfd);
                    if (maxi < i) {
                        maxi = i;
                    }
                    break;
                }
            }
        }

        for (i=0; i<=maxi; i++) {
            if (client[i] < 0) {
                continue;
            }
            printf("i=%d, listenfd=%d, clifd = %d, maxfd=%d\n", i, listenfd, connfd, maxfd);
            if (FD_ISSET(client[i], &rset)) {
                if ( (n=Recv(client[i], buf, sizeof(buf), 0)) == 0) {
                    close(client[i]);
                    FD_CLR(client[i], &allset);
                    client[i] = -1;
                    continue;
                }
                Writen(client[i], buf, n);
            }
        }
    }
}

